package edu.uob;

import java.io.File;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;

public class CommandHandler {

    public static String handleCommand(Cmd parsedCommand) {
        CmdType cmdType = parsedCommand.type();

        if (cmdType.getType() == CmdTypeEnum.USE) {
            setCurrentDatabasePath(CmdType.getDbName());
            return "[OK]";
        } else if (cmdType.getType() == CmdTypeEnum.CREATE_DB) {
            return DatabaseCreator.createDatabase(CmdType.getDbName());
        } else if (cmdType.getType() == CmdTypeEnum.CREATE_TBL) {
            return TableCreator.createTable(CmdType.getTblName());
        } else if (cmdType.getType() == CmdTypeEnum.CREATE_ATTR) {
            String file_name = "." + File.separator + "databases" + File.separator + CmdType.getDbName() + File.separator + CmdType.getTblName() + ".tab";
            String attrs = cmdType.getAttrList().toString();
            attrs = "id," + attrs.substring(1, attrs.length() - 1);
            attrs = attrs.replace(" ", "");
            return TabWriter.write(file_name, attrs);
        } else if (cmdType.getType() == CmdTypeEnum.DROP_DB) {
            return DatabaseManager.dropDB(CmdType.getDbName());
        } else if (cmdType.getType() == CmdTypeEnum.DROP_TBL) {
            if (tableExists(CmdType.getTblName())) {
                return TableManager.dropTable(CmdType.getTblName());
            } else {
                return "[ERROR]: Table does not exist!";
            }
        } else if (cmdType.getType() == CmdTypeEnum.ALTER_ADD) {
            if (tableExists(CmdType.getTblName())) {
                return addAttribute.add(CmdType.getTblName(), cmdType.getAttributeName());
            } else {
                return "[ERROR]: Table does not exist!";
            }
        } else if (cmdType.getType() == CmdTypeEnum.ALTER_DROP) {
            if (tableExists(CmdType.getTblName())) {
                return DropAttribute.drop(CmdType.getTblName(), cmdType.getAttributeName());
            } else {
                return "[ERROR]: Table does not exist!";
            }
        } else if (cmdType.getType() == CmdTypeEnum.INSERT) {
            if (tableExists(CmdType.getTblName())) {
                String Value = cmdType.getAttrList().toString();
                Value = "id," + Value.substring(1, Value.length() - 1);
                Value = Value.replace(" ", "");
                return Table.insertRow(CmdType.getTblName(), Value);
            } else {
                return "[ERROR]: Table does not exist!";
            }
        } else if (cmdType.getType() == CmdTypeEnum.SELECT || cmdType.getType() == CmdTypeEnum.SELECT_WH) {
            String file_name = "." + File.separator + "databases" + File.separator + CmdType.getDbName() + File.separator + CmdType.getTblName() + ".tab";
            File tableFile = new File(file_name);
            if (!tableFile.exists()) {
                return "[ERROR]: Table file does not exist!";
            }
            List<String> wildAttribList = cmdType.getWildAttribList();
            String wildAttribString = String.join(",", wildAttribList);
            Table table = TableReader.readTableFromFile(file_name);
            if (!wildAttribString.equals("*")) {
                // Check if WildAttribList exists in the table
                if (!wildAttribExists(table, wildAttribString)) {
                    return "[ERROR]: Attribute does not exist!";
                }
            }
            String query = CmdType.getQuery();
            List<Map<String, Object>> result = QueryParser.executeQuery(table, query);
            // Output the result as a table
            StringBuilder output = new StringBuilder();
            output.append("[OK]\n");

            // Output header
            if (wildAttribString.equals("*")) {
                // Output all columns
                for (String attrib : Table.getColumnNames()) {
                    output.append(String.format("%-10s", attrib));
                }
                output.append("\n");
            } else {
                // Output selected columns
                String[] attribs = wildAttribString.split(",");
                for (String attrib : attribs) {
                    output.append(String.format("%-10s", attrib.trim()));
                }
                output.append("\n");
            }

            // Output data
            for (Map<String, Object> row : result) {
                if (wildAttribString.equals("*")) {
                    // Output all columns
                    for (String attrib : Table.getColumnNames()) {
                        output.append(String.format("%-10s", row.get(attrib)));
                    }
                    output.append("\n");
                } else {
                    // Output selected columns
                    String[] attribs = wildAttribString.split(",");
                    for (String attrib : attribs) {
                        output.append(String.format("%-10s", row.get(attrib.trim())));
                    }
                    output.append("\n");
                }
            }

            return output.toString();
        } else if (cmdType.getType() == CmdTypeEnum.UPDATE) {
            String file_name = "." + File.separator + "databases" + File.separator + CmdType.getDbName() + File.separator + CmdType.getTblName() + ".tab";
            File tableFile = new File(file_name);
            if (!tableFile.exists()) {
                return "[ERROR]: Table file does not exist!";
            }
            Table table = TableReader.readTableFromFile(file_name);
            List<String> NameValueList = cmdType.getWildAttribList();

            UpdateCondition.UpdateCondition1(table, CmdType.getCondition(), NameValueList);

            return "[OK]";
        } else if (cmdType.getType() == CmdTypeEnum.DELETE) {
            String file_name = "." + File.separator + "databases" + File.separator + CmdType.getDbName() + File.separator + CmdType.getTblName() + ".tab";
            File tableFile = new File(file_name);
            if (!tableFile.exists()) {
                return "[ERROR]: Table file does not exist!";
            }
            Table table = TableReader.readTableFromFile(file_name);

            DeleteCondition.handleCondition(table, CmdType.getCondition());

            return "[OK]";
        } else {
            return "[ERROR]: Unsupported command type!";
        }
    }

    private static void setCurrentDatabasePath(String databaseName) {
        String storageFolderPath = "";
        Paths.get(storageFolderPath, databaseName);
    }

    private static boolean tableExists(String tableName) {
        String file_name = "." + File.separator + "databases" + File.separator + CmdType.getDbName() + File.separator + tableName + ".tab";
        File tableFile = new File(file_name);
        return tableFile.exists();
    }
    private static boolean wildAttribExists(Table table, String wildAttribList) {
        // Split the WildAttribList into individual attributes
        String[] attribs = wildAttribList.split(",");

        // Check if each attribute exists in the table
        for (String attrib : attribs) {
            if (!Table.getColumnNames().contains(attrib.trim())) {
                return false;
            }
        }

        return true;
    }
}
